home *** CD-ROM | disk | FTP | other *** search
- // Battery Plug In for Now Tabs
- // ©1996 Now Software, Inc, Now Utilities Division
- //
- // written by: Henry Carstens, 3/2/96
- //
- // This plug in displays the current status of a powerbook or Duo's battery:
- // - whether or not it is charging
- // - the percentage of charge remaining
- // - the approximate time remaining on this battery
- //
-
- #include "Main.h"
- #include "Power.h"
- #include "Gestalt.h"
-
- #define canGetBatteryTimeMask 0x07
- #define chargerConnectedMask 0x05
- #define chargerChargingMask 0x06
- #define batteryInstalledMask 0x07
-
- // This routine sets up the plug in definition version: kPlugInInformationVersionOne in this rev
- // and the plug in type: kBatteryPlugInType. Your own plug-ins will have their own types.
- // We'll want our plug in routines called when the Tabs menu is prepared
- // and when our plug in is selected if we are going to 'say' anything (speech mgr).
- pascal void main(PlugInInformation *plugInInformation)
- {
- plugInInformation->version = kPlugInInformationVersionOne;
- plugInInformation->plugInType = kBatteryPlugInType;
- plugInInformation->PrepareMenu = &PrepareMenu;
- plugInInformation->HandleMenuItemSelected = &HandleMenuItemSelected;
- }
-
- // Use this routine to build your menu item
- // In our case we'll check to see if the PowerManager is available
- // and then determing the battery status.
- // We'll also use this routine to set up our globals.
- pascal void PrepareMenu(InstantAccessInformation *information, short asPreview)
- {
- long battery;
- short batteryCount;
- BatteryInfo batteryInfo;
- BatteryTimeRec batterySecs;
- Str255 batteryString;
- Boolean hasBatteryTime;
- OSErr err;
- long features;
- short index;
- MenuItemInformation menuItem;
- Byte power;
- double realPower;
- long response;
- Byte status;
- Str15 tempStr;
- Str15 tempStr2;
- unsigned long timeRemaining;
-
- // Check to see if the Power Manager exists on this machine
- err = Gestalt(gestaltPowerMgrAttr, &response);
- if ( ( err != noErr) || (response == 0) ) { // gestaltPwrMgrExists == 0
- goto error;
- }
-
- // Check to see if the charger is connected
- err = BatteryStatus(&status,&power);
- if (err != noErr) goto error;
-
- // Find out what features of the Power Manager we can use
- features = PMFeatures();
-
- // see if we can get the time to charge or time remaining
- hasBatteryTime = features && canGetBatteryTimeMask;
-
- // get number of batteries
- batteryCount = BatteryCount();
-
- // Now, we'll build up a little battery database
- // which we'll display in our menu
- for (index = 1; index <= batteryCount; index++) {
-
- batteryString[0] = 0;
-
- // get the info for each battery
- GetScaledBatteryInfo(index, &batteryInfo);
-
- // is there a battery installed?
- if (!(batteryInfo.flags && batteryInstalledMask)) {
- continue;
- }
-
- if (hasBatteryTime) {
- GetBatteryTimes(index, &batterySecs);
-
- if ( (status && chargerConnMask) && (batteryInfo.flags && chargerConnectedMask) && (batteryInfo.flags && chargerChargingMask) ) {
- timeRemaining = batterySecs.timeUntilCharged;
- } else {
- timeRemaining = batterySecs.expectedBatteryTime;
- }
-
- // set sign bit to 0
- BitClr(&timeRemaining, 0);
-
- timeRemaining = timeRemaining / 60;
-
- NumToString(timeRemaining, tempStr);
-
- } else {
- tempStr[0] = 0;
- }
-
- // start w/ the battery status message
- BlockMove("Battery ", &batteryString[1], 8);
- batteryString[0] = 8;
-
- // add the battery number
- if (batteryCount > 1) {
- NumToString(index,tempStr2);
- BlockMove(&tempStr2[1], &batteryString[batteryString[0] + 1], tempStr2[0]);
- batteryString[0] += tempStr2[0];
- }
-
- // check for unknown time remaining - over 10 hours
- if (timeRemaining > 600) {
- tempStr[0] = 0;
- }
-
- // finish the string
- BlockMove("Status: ", &batteryString[batteryString[0] + 1], 8);
- batteryString[0] += 8;
-
- if ( (status && chargerConnMask) && (batteryInfo.flags && chargerConnectedMask) && (batteryInfo.flags && chargerChargingMask) ) {
-
- // battery is charged if overflow is true
- if (status && chargeOverFlowMask) {
- BlockMove("Charged ", &batteryString[batteryString[0] + 1], 7);
- batteryString[0] += 7;
- } else {
- BlockMove("Charging ", &batteryString[batteryString[0] + 1], 9);
- batteryString[0] += 9;
- }
-
- } else {
- // we know the time remaining
- if (tempStr[0] != 0) {
- BlockMove("Remaining ", &batteryString[batteryString[0] + 1], 10);
- batteryString[0] += 10;
-
- // we don't know the time remaining
- } else {
- BlockMove("Discharging", &batteryString[batteryString[0] + 1], 11);
- batteryString[0] += 11;
- }
- }
-
- // time remaining - check for no time value
- if (tempStr[0] != 0) {
- BlockMove(&tempStr[1], &batteryString[batteryString[0] + 1], tempStr[0]);
- batteryString[0] += tempStr[0];
-
- BlockMove(" minutes", &batteryString[batteryString[0] + 1], 8);
- batteryString[0] += 8;
- }
-
- // Move our constructed menu string into the menuItem.text variable
- // Always use kMenuItemTextSize in this routine
- BlockMove(batteryString, menuItem.text, kMenuItemTextSize);
-
- // First, let's add a divider to seperate us from the rest of the world
- if (index == 1) {
- menuItem.version = kMenuItemInformationVersionOne;
- menuItem.classification = kMiscellaneousClassification;
- menuItem.type = kDividerMenuItemType;
- menuItem.id = 1;
- menuItem.enabled = false;
- menuItem.style = 0;
- menuItem.mark = 0;
- menuItem.hasSubMenu = FALSE;
- menuItem.subMenu = nil;
- menuItem.refCon = 0;
- menuItem.owningPlugInType = kBatteryPlugInType;
-
- // This call adds the menuItem to the Now Tabs menu
- (*information->AddMenuItem)(&menuItem);
- }
-
- // Here we fill out the rest of the menuItem information
- // You'll need to insert your plug in type in the owningPlugInType field
- menuItem.type = kTextMenuItemType;
- menuItem.id = index + 1;
- menuItem.enabled = true;
-
- // This call adds the menuItem to the Now Tabs menu
- (*information->AddMenuItem)(&menuItem);
-
- if (index == batteryCount) {
-
- // Add a divider below
- menuItem.type = kDividerMenuItemType;
- menuItem.id = index + 2;
- menuItem.enabled = false;
-
- // This call adds the menuItem to the Now Tabs menu
- (*information->AddMenuItem)(&menuItem);
- }
- }
-
- error:;
-
- }
-
- // If we had allocated any memory during the call to menu select that we
- // still needed to clean up, we would do the clean up here
- pascal void CleanUpAfterMenuSelect(InstantAccessInformation *information, short asPreview)
- {
-
- }
-
- // This routine is called when your menu item is selected by the user so add your
- // selection routines here...
- pascal void HandleMenuItemSelected(InstantAccessInformation *information, MenuItemInformation *menuItem)
- {
- // If speech manager is present, say "You have x minutes of power remaining."
- // If speech manager is present, say "Dammit Jim, I'm a doctor, not a battery specialist"
- }
-